<template>
  <view class="login">
    <!-- 顶部自定义导航 -->
    <TnNavbar fixed alpha customBack :placeholder="false" bg-color="transparent" :bottom-shadow="false">
      <view slot="back" class='tn-custom-nav-bar__back'>
        <text class='icon tn-icon-left'></text>
        <text class='icon tn-icon-home-capsule-fill'></text>
      </view>
    </TnNavbar>
    <!-- 顶部背景图片-->
    <view class="login__bg login__bg--top">
      <image class="bg" src="https://resource.tuniaokj.com/images/login/1/login_top2.jpg" mode="widthFix"></image>
    </view>
    <view class="login__bg login__bg--top">
      <image class="rocket rocket-sussuspension" src="https://resource.tuniaokj.com/images/login/1/login_top3.png"
             mode="widthFix"></image>
    </view>
    <!-- 输入框内容-->
    <view
        class="login__info flex flex-direction align-center justify-center">
      <view class="tn-p-sm">
        <view>① 看一个视频支持一下吧，仅需观看一次，48小时内不再限制，赏个月卡耍耍，感谢各位大佬了。</view>
        <view class="margin-tb-sm">② <text class="text-red">完整观看视频</text>或<text class="text-red">完成指定要求</text>后，点击关闭，即视为有效，小程序将不再弹出激励广告。</view>
        <view>③ <text class="text-red">请勿删除小程序, 否则广告限制时间将会重置。</text></view>
        <view class="margin-top-sm">④ <text class="text-red">广告具体内容由微信提供，小程序无法控制, 敬请谅解。</text></view>
      </view>
      <view @click="watchAd" class="login__info__item__button bg-gradual-blue" hover-class="tn-hover" :hover-stay-time="150">
        点击观看
      </view>
    </view>


    <!-- 底部背景图片-->
    <view class="login__bg login__bg--bottom">
      <image src="https://resource.tuniaokj.com/images/login/1/login_bottom_bg.jpg" mode="widthFix"></image>
    </view>

    <canvas
        v-if="showCanvas"
        canvas-id="bubble"
        id="bubble"
        class="bubble"
        :style="{width: `${windowWidth}px`, height: `${windowHeight}px`}"
    ></canvas>
  </view>
</template>

<script setup>
  import TnNavbar from "../../uni_modules/tuniaoui-vue3/components/navbar/src/navbar.vue";
  import {setAd} from "../../storage/ad";
  import {onLoad, onUnload} from '@dcloudio/uni-app'
  import {ref, getCurrentInstance} from 'vue'
  import {setNow} from "../../storage/now";

  const url = ref('')

  // 在页面中定义激励视频广告
  let videoAd = null

  // 在页面onLoad回调事件中创建激励视频广告实例
  if (wx.createRewardedVideoAd) {
    videoAd = wx.createRewardedVideoAd({
      adUnitId: 'adunit-be4fe1457c390cd4'
    })
    videoAd.onLoad(() => {})
    videoAd.onError((err) => {
      console.error('激励视频光告加载失败', err)
    })
    videoAd.onClose((res) => {
      if(res.isEnded) {
        setAd(false)
        setNow(new Date().getTime())
        uni.redirectTo({
          url: url.value
        })
      }
    })
  }

  // 用户触发广告后，显示激励视频广告
  const watchAd = () => {
    if (videoAd) {
      videoAd.show().catch(() => {
        // 失败重试
        videoAd.load()
            .then(() => videoAd.show())
            .catch(err => {
              console.error('激励视频 广告显示失败', err)
            })
      })
    }
  }

  // 气泡特效
  const windowHeight = ref(0)
  const windowWidth = ref(0)
  const startTimer = ref(null)
  const actionTimer = ref(null)
  const animationTimer = ref(null)
  const queue = ref({})
  const ctx = ref(null)

  const getSystemInfo = () => {
    const systemInfo = uni.getSystemInfoSync()
    if (!systemInfo) {
      setTimeout(() => {
        getSystemInfo()
      }, 50)
      return
    }

    windowHeight.value = systemInfo.safeArea.height
    windowWidth.value = systemInfo.safeArea.width
  }

  const randomInt = (min, max) => {
    if (min >= 0 && max > 0 && max >= min) {
      let gab = max - min + 1
      return Math.floor(Math.random() * gab + min)
    } else {
      return 0
    }
  }

  const random = (min, max) => {
    if (min >= 0 && max > 0 && max >= min) {
      let gab = max - min
      return Math.random() * gab + min
    } else {
      return 0
    }
  }

  const generateBubble = () => {
    const image = "https://seerh5.61.com/resource/assets/PetType/" + randomInt(1, 122) + ".png"
    uni.getImageInfo({
      src: image,
      success: (res) => {
        if (res.errMsg === 'getImageInfo:ok') {
          const anmationData = {
            id: new Date().getTime(),
            timer: 0,
            opacity: 0,
            pathData: generatePathData(),
            image: res.path,
            factor: {
              speed: 0.0006, // 运动速度，值越小越慢
              t: 0.1 //  贝塞尔函数系数，当为0，就是从无到有，这时候屏幕高度也要调一下
            }
          }
          if (Object.keys(queue.value).length > 0) {
            queue.value[anmationData.id] = anmationData
          } else {
            queue.value[anmationData.id] = anmationData
            bubbleAnimate()
          }
        }
      }
    })
  }

  /* 动画相关 */
  // 生成运动的路径数据
  const generatePathData = () => {
    let width = windowWidth.value,
        height = windowHeight.value;
    const p0 = {
      x: 0.72 * width,
      y: height
    }
    const p1 = {
      x: random(0.22 * width, 0.33 * width),
      y: random(0.5 * height, 0.75 * height)
    }
    const p2 = {
      x: random(0, 0.88 * width),
      y: random(0.25 * height, 0.5 * height)
    }
    const p3 = {
      x: random(0, 0.88 * width),
      y: random(0, 0.125 * height)
    }
    return [p0, p1, p2, p3]
  }

  // 更新运动的路径
  const updatePath = (data, factor) => {
    const p0 = data[0]
    const p1 = data[1]
    const p2 = data[2]
    const p3 = data[3]

    const t = factor.t

    /*计算多项式系数 （下同）*/
    const cx1 = 3 * (p1.x - p0.x)
    const bx1 = 3 * (p2.x - p1.x) - cx1
    const ax1 = p3.x - p0.x - cx1 - bx1

    const cy1 = 3 * (p1.y - p0.y)
    const by1 = 3 * (p2.y - p1.y) - cy1
    const ay1 = p3.y - p0.y - cy1 - by1

    const x = ax1 * (t * t * t) + bx1 * (t * t) + cx1 * t + p0.x
    const y = ay1 * (t * t * t) + by1 * (t * t) + cy1 * t + p0.y
    // console.log(p0.y, p1.y, p2.y, p3.y, y);
    return {
      x,
      y
    }
  }

  // 执行泡泡动画
  const bubbleAnimate = () => {
    let width = windowWidth.value,
        height = windowHeight.value;
    Object.keys(queue.value).forEach(key => {
      const anmationData = queue.value[+key];
      const {
        x,
        y
      } = updatePath(
          anmationData.pathData,
          anmationData.factor
      )
      const speed = anmationData.factor.speed
      anmationData.factor.t += speed

      let curWidth = 30
      curWidth = (height - y) / 1.5
      curWidth = Math.min(30, curWidth)

      let curAlpha = anmationData.opacity
      curAlpha = y / (0.3 * height) //消失的高度适当调一下
      curAlpha = Math.min(1, curAlpha)
      ctx.value.globalAlpha = curAlpha
      ctx.value.drawImage(anmationData.image, x - curWidth / 2, y, curWidth, curWidth)
      if (anmationData.factor.t > 1) {
        delete queue.value[anmationData.id]
      }
      if (y > height) {
        delete queue.value[anmationData.id]
      }
    })
    ctx.value.draw()
    if (Object.keys(queue.value).length > 0) {
      animationTimer.value = setTimeout(() => {
        bubbleAnimate()
      }, 5)
    } else {
      clearAnimationTimer()
      ctx.value.draw() // 清空画面
    }
  }

  // 清除定时器
  const clearActionTimer = () => {
    if (actionTimer.value) {
      clearInterval(actionTimer.value)
    }
  }

  const clearAnimationTimer = () => {
    if (animationTimer.value) {
      clearInterval(animationTimer.value)
    }
  }

  const clearStartTimer = () => {
    if (startTimer.value) {
      clearTimeout(startTimer.value)
    }
  }

  const {proxy} = getCurrentInstance()

  const showCanvas = ref(false)

  const start = () => {
    showCanvas.value = true
    queue.value = {}
    ctx.value = uni.createCanvasContext("bubble", proxy)

    startTimer.value = setTimeout(() => {
      actionTimer.value = setInterval(() => {
        generateBubble()
      }, 1500)
    }, 1000)

    getSystemInfo()
  }

  const startBubble = () => {
    if (!showCanvas.value) {
      showCanvas.value = true
      queue.value = {}
      ctx.value = uni.createCanvasContext("bubble", proxy)

      if (startTimer.value) clearTimeout(startTimer.value)
      if (actionTimer.value) clearInterval(actionTimer.value)
      startTimer.value = setTimeout(() => {
        actionTimer.value = setInterval(() => {
          generateBubble()
        }, 500)
      }, 1000)

      getSystemInfo()
    }
  }

  onLoad((res) => {
    url.value = JSON.parse(decodeURIComponent(res.url))
    setTimeout(() => {
      startBubble()
    }, 500)
  })

  onUnload(() => {
    showCanvas.value = false
    clearStartTimer()
    clearActionTimer()
    clearAnimationTimer()
  })
</script>


<style scoped lang="scss">
  /* 悬浮 */
  .rocket-sussuspension {
    animation: suspension 3s ease-in-out infinite;
  }

  @keyframes suspension {
    0%, 100% {
      transform: translate(0, 0);
    }
    50% {
      transform: translate(-0.8rem, 1rem);
    }
  }

  .login {
    position: relative;
    height: 100%;
    z-index: 1;

    /* 背景图片 start */
    &__bg {
      z-index: -1;
      position: fixed;

      &--top {
        top: 0;
        left: 0;
        right: 0;
        width: 100%;

        .bg {
          width: 750rpx;
          will-change: transform;
        }

        .rocket {
          margin: 50rpx 28%;
          width: 400rpx;
          will-change: transform;
        }
      }

      &--bottom {
        bottom: -10rpx;
        left: 0;
        right: 0;
        width: 100%;
        // height: 144px;
        margin-bottom: env(safe-area-inset-bottom);

        image {
          width: 750rpx;
          will-change: transform;
        }
      }
    }
    /* 背景图片 end */

    /* 登录注册信息 start */
    &__info {
      width: 95%;
      position: fixed;
      top: 30%;
      left: 50%;
      transform: translateX(-50%);
      padding: 30rpx 51rpx;
      padding-bottom: 0;
      border-radius: 20rpx;
      background-color: #ffff;
      box-shadow: 0rpx 10rpx 50rpx 0rpx rgba(0, 3, 72, 0.1);

      &__item {

        &__input {
          margin-top: 59rpx;
          width: 100%;
          height: 77rpx;
          border: 1rpx solid #E6E6E6;
          border-radius: 39rpx;

          &__left-icon {
            width: 10%;
            font-size: 44rpx;
            margin-left: 20rpx;
            color: #AAAAAA;
          }

          &__content {
            width: 80%;
            padding-left: 10rpx;

            &--verify-code {
              width: 56%;
            }

            input {
              font-size: 24rpx;
              // letter-spacing: 0.1em;
            }
          }

          &__right-icon {
            width: 10%;
            font-size: 44rpx;
            margin-right: 20rpx;
            color: #AAAAAA;
          }

          &__right-verify-code {
            width: 34%;
            margin-right: 20rpx;
          }
        }

        &__button {
          margin: 40rpx 0;
          width: 100%;
          height: 77rpx;
          text-align: center;
          font-size: 31rpx;
          font-weight: bold;
          line-height: 77rpx;
          letter-spacing: 1em;
          text-indent: 1em;
          border-radius: 39rpx;
          box-shadow: 1rpx 10rpx 24rpx 0rpx rgba(60, 129, 254, 0.35);
        }

        &__tips {
          margin: 30rpx 0;
          color: #AAAAAA;
        }
      }
    }

    /* 登录注册信息 end */

    /* 登录方式切换 start */
    &__way {
      margin: 110rpx auto 0;

      &__item {
        &--icon {
          width: 77rpx;
          height: 77rpx;
          font-size: 50rpx;
          border-radius: 100rpx;
          margin-bottom: 18rpx;
          position: relative;
          z-index: 1;

          &::after {
            content: " ";
            position: absolute;
            z-index: -1;
            width: 100%;
            height: 100%;
            left: 0;
            bottom: 0;
            border-radius: inherit;
            opacity: 1;
            transform: scale(1, 1);
            background-size: 100% 100%;
            background-image: url(https://resource.tuniaokj.com/images/cool_bg_image/icon_bg5.png);
          }
        }
      }
    }

    /* 登录方式切换 end */
    /* 内容 end */

  }

  .bubble {
    position: fixed;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    width: 100%;
    height: 100%;
    z-index: 1024;
    pointer-events: none;
  }
</style>
